package com.sunwayworld.basemodule.business.result.io;

import com.sunwayworld.baseline.framework.override.LimsExcelHelper;
import com.sunwayworld.basemodule.business.ordertask.bean.LimsOrderTaskBean;
import com.sunwayworld.basemodule.business.result.bean.LimsResultBean;
import com.sunwayworld.basemodule.business.result.computing.OrderTaskResultComputingEngine;
import com.sunwayworld.basemodule.business.result.service.LimsResultService;
import com.sunwayworld.basemodule.coredata.test.bean.LimsPossibleResultBean;
import com.sunwayworld.basemodule.coredata.test.service.LimsPossibleResultService;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.io.file.FilePathDTO;
import com.sunwayworld.framework.io.file.FilePathManager;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.CollectionUtils;
import com.sunwayworld.framework.utils.StringUtils;
import com.sunwayworld.module.item.file.bean.CoreFileBean;
import com.sunwayworld.module.item.file.bean.CoreFileImportResultDTO;
import com.sunwayworld.module.item.file.function.CoreFileImportFunction;
import com.sunwayworld.module.item.file.utils.CoreFileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component(value = "limsResultImportFileFunction")
@GikamBean
public class LimsResultImportFileFunction implements CoreFileImportFunction {

    @Autowired
    private LimsResultService resultService;

    @Autowired
    private LimsPossibleResultService possibleResultService;

    @Override
    public CoreFileImportResultDTO apply(CoreFileBean coreFileBean) {
        CoreFileImportResultDTO importResultRepresentation = new CoreFileImportResultDTO();
        FilePathDTO fr = CoreFileUtils.toFilePath(coreFileBean);

        List<LimsOrderTaskBean> orderTasks =
                LimsExcelHelper.readDataFromExcel(FilePathManager.getLocalPath(fr).toString(),
                        0, 1, LimsOrderTaskBean.class);
        if (!orderTasks.isEmpty()) {
            // 返还校验结果
            if (orderTasks.stream().anyMatch(i -> !StringUtils.isEmpty(i.getExt$Item("validateimpmsg")))) {
                FilePathDTO filePathDTO = LimsExcelHelper.writeImportFailureListAsExcel(FilePathManager.getLocalPath(fr).toString(), orderTasks, 0, 1, "导入错误信息.xlsx", false);
                importResultRepresentation.setUrl(FilePathManager.getUrl(filePathDTO));
                importResultRepresentation.setMessage("导入失败");
                return importResultRepresentation;
            }
        }

        // 设置结果
        List<Long> orderTaskIdList = orderTasks.stream().map(LimsOrderTaskBean::getId).collect(Collectors.toList());
        List<LimsResultBean> resultBeanList = resultService.getDao().selectListByOneColumnValues(orderTaskIdList, "orderTaskId"
                , Arrays.asList("id", "folderId", "orderTaskId", "analyteId", "analyte", "analType", "editFlag", "writeFlag", "hideFlag"));

        // 过滤掉隐藏的分析项
        resultBeanList = resultBeanList.stream().filter(r -> !StringUtils.equals(r.getHideFlag(), "1")).collect(Collectors.toList());
        Map<Long, List<LimsResultBean>> resultMap = resultBeanList.stream().collect(Collectors.groupingBy(LimsResultBean::getOrderTaskId));
        for (LimsOrderTaskBean orderTaskBean : orderTasks) {
            List<LimsResultBean> resultBeans = resultMap.get(orderTaskBean.getId());
            Map<String, String> map = orderTaskBean.getExt$();
            for (LimsResultBean resultBean : resultBeans) {
                resultBean.setOriginalResult(map.get(resultBean.getAnalyteId().toString()));
            }
        }

        if (resultBeanList.isEmpty()) {
            return importResultRepresentation;
        } else {
            List<LimsPossibleResultBean> possibleResultBeanList = possibleResultService.selectListByFilter(SearchFilter.instance()
                    .match("analyteId", resultBeanList.stream().map(LimsResultBean::getAnalyteId).distinct().collect(Collectors.toList())).filter(MatchPattern.OR));
            Map<Long, List<LimsPossibleResultBean>> possibleResultMap = possibleResultBeanList.stream().collect(Collectors.groupingBy(LimsPossibleResultBean::getAnalyteId));
            resultBeanList.parallelStream().forEach(resultBean -> {
                // 校验分析项填写值是否在备选内容内
                if (!StringUtils.isEmpty(resultBean.getOriginalResult())) {
                    List<LimsPossibleResultBean> possibleResultList = possibleResultMap.get(resultBean.getAnalyteId());
                    if (!CollectionUtils.isEmpty(possibleResultList) && possibleResultList.stream().noneMatch(p ->
                            StringUtils.equals(p.getFinalResult(), resultBean.getOriginalResult()))) {
                        String message = I18nHelper.getMessage("T_CORE_ITEM.SERVICE_NAME") + "【" + resultBean.getAnalyte() + "】" + I18nHelper.getMessage("IMPORT.VALUE.NOT.IN.POSSIBALESELECT") + "；";
                        orderTasks.stream().filter(ot -> ot.getId().equals(resultBean.getOrderTaskId())).findAny().ifPresent(a -> {
                            if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                                a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat(message));
                            } else {
                                a.setExt$Item("validateimpmsg", message);
                            }
                        });
                    }
                } else {
                    if (StringUtils.equals(resultBean.getWriteFlag(), "1")) {
                        if (StringUtils.isBlank(resultBean.getOriginalResult())) {
                            orderTasks.stream().filter(ot -> ot.getId().equals(resultBean.getOrderTaskId())).findAny().ifPresent(a -> {
                                if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                                    a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【").concat(resultBean.getAnalyte()).concat("】").concat("分析项必须填写；"));
                                } else {
                                    a.setExt$Item("validateimpmsg", "【".concat(resultBean.getAnalyte()).concat("】").concat("分析项必须填写；"));
                                }
                            });
                        }
                    }
                }
                if ("D".equalsIgnoreCase(resultBean.getAnalType()) && !StringUtils.isEmpty(resultBean.getOriginalResult())) {
                    if (!isValidDate(resultBean.getOriginalResult())) {
                        orderTasks.stream().filter(ot -> ot.getId().equals(resultBean.getOrderTaskId())).findAny().ifPresent(a -> {
                            if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                                a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("【").concat(resultBean.getAnalyte()).concat("】").concat(I18nHelper.getMessage("RESULT_UPLOAD_DATETIME_CHECK")));
                            } else {
                                a.setExt$Item("validateimpmsg", "【".concat(resultBean.getAnalyte()).concat("】").concat(I18nHelper.getMessage("RESULT_UPLOAD_DATETIME_CHECK")));
                            }
                        });
                    }
                }
                if ("N".equalsIgnoreCase(resultBean.getAnalType()) && !StringUtils.isEmpty(resultBean.getOriginalResult())) {
                    try {
                        Double num = Double.parseDouble(resultBean.getOriginalResult());
                    } catch (Exception e) {
                        orderTasks.stream().filter(ot -> ot.getId().equals(resultBean.getOrderTaskId())).findAny().ifPresent(a -> {
                            if (!StringUtils.isBlank(a.getExt$Item("validateimpmsg"))) {
                                a.setExt$Item("validateimpmsg", a.getExt$Item("validateimpmsg").concat("分析项【").concat(resultBean.getAnalyte()).concat("】应填写数值型结果；"));
                            } else {
                                a.setExt$Item("validateimpmsg", "分析项【".concat(resultBean.getAnalyte()).concat("】应填写数值型结果；"));
                            }
                        });
                    }
                }
            });

            // 返还校验结果
            if (orderTasks.stream().anyMatch(i -> !StringUtils.isEmpty(i.getExt$Item("validateimpmsg")))) {
                FilePathDTO filePathDTO = LimsExcelHelper.writeImportFailureListAsExcel(FilePathManager.getLocalPath(fr).toString(), orderTasks, 0, 1, "导入错误信息.xlsx", false);
                importResultRepresentation.setUrl(FilePathManager.getUrl(filePathDTO));
                importResultRepresentation.setMessage("导入失败");
                return importResultRepresentation;
            }

            resultService.getDao().fastUpdate(resultBeanList, "ORIGINALRESULT");
            //增加公式计算
            List<Long> folderIdList = resultBeanList.stream().map(LimsResultBean::getFolderId).distinct().collect(Collectors.toList());
            OrderTaskResultComputingEngine.getEngine(folderIdList, "com.sunwayworld.baseline.business.ordertask.computing.formula.OrderTaskFormulaRepository").compute();
        }
        importResultRepresentation.setMessage("导入成功");
        return importResultRepresentation;
    }

    public static boolean isValidDate(String str) {
        boolean convertSuccess = true;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            format.setLenient(false);
            format.parse(str);
        } catch (Exception e) {
            convertSuccess = false;
        }
        return convertSuccess;
    }

    @Override
    public boolean test(CoreFileBean coreFile, String service) {
        return true;
    }
}
